﻿#define _CRT_SECURE_NO_WARNINGS 2
//2024-3-24 Sunday 16:08:29 March3月
//第16讲：字符函数和字符串函数
//⽬录：
//1. 字符分类函数
//2. 字符转换函数
//3. strlen的使⽤和模拟实现
//4. strcpy的使⽤和模拟实现
//5. strcat的使⽤和模拟实现
//6. strcmp的使⽤和模拟实现
//7. strncpy函数的使⽤
//8. strncat函数的使⽤
//9. strncmp函数的使⽤
//10. strstr的使⽤和模拟实现
//11. strtok函数的使⽤
//12. strerror函数的使⽤

//3. strlen的使⽤和模拟实现
//size-t my_strlen(const char* str)
//指针-指针 --> 地址-地址
//得到的指针和指针之间的元素个数
//#include <stdio.h>
//#include <assert.h>
//
//size_t my_strlen(const char* str)
//{
//	assert(str);
//	const char* start = str;
//
//	//下一种自己写的，发现也行，因为地址一样
//	//while (*str != '\0')
//	while (*start != '\0')
//	{
//		//str++; //算上\0
//		start++;
//	}
//
//	//return str - start;
//	//return start - str; 
//}
//
//int main()
//{
//	char arr[] = "abc" ;
//
//	printf("len == %zd\n", my_strlen(arr));
//
//	return 0;
//}
//1
//2
//方法3 - 递归的方式
//模拟实现strlen函数，不能使用临时变量
//递归的思想：大事化小
//1 + my_strlen("abc") //如果a != '\0'，长度为1
//1 + 1 + my_strlen("bc") //b != '\0'，长度为2
//1 + 1 + 1 + my_strlen("c")
//1 + 1 + 1 + my_strlen("");
//1 + 1 + 1 + 0 = 3 //否则*str == '\0'，返回0

//#include <stdio.h>
//
//size_t my_strlen(const char* str)
//{
//	assert(str);
//
//	if (*str != '\0')
//	{
//		return 1 + my_strlen(str + 1); //让地址往后走，一个字符一个字符的判断
//		                  //(++str) //error
//		                  //(str++) //不推荐，因为这样使得str变化了
//	}
//	else
//	{
//		return 0;
//	}
//}
//
//int main()
//{
//	char arr[] = "abc";
//
//	printf("len == %zd\n", my_strlen(arr));
//
//	return 0;
//}
//1
//2
//3
//4
//5
//第16讲：字符函数和字符串函数
//⽬录：
//1. 字符分类函数
//2. 字符转换函数
//3. strlen的使⽤和模拟实现
//4. strcpy的使⽤和模拟实现
//5. strcat的使⽤和模拟实现
//6. strcmp的使⽤和模拟实现
//7. strncpy函数的使⽤
//8. strncat函数的使⽤
//9. strncmp函数的使⽤
//10. strstr的使⽤和模拟实现
//11. strtok函数的使⽤
//12. strerror函数的使⽤

//4. strcpy的使⽤和模拟实现
//char* strcpy(char* destination, const char* soure)
//函数的功能：拷贝字符串(可以理解成字符赋值)
//注意事项：
//1. 源字符串中必须包含\0，同时\0也会被拷贝到目标空间
//2. 程序员自己要保证目标空间足够大，能放得下拷贝来的数据
//3. 保证目标空间必须可以修改
//#include <stdio.h>
//#include <string.h>
//
//int main()
//{
//	char arr[] = "abcdefg";
//	char arr2[] = "xxx";
//	strcpy(arr, arr2);
//	printf("%s", arr);

	// 
	//char arr[] = { 'a', 'b', 'c', '\0' };
	//char arr2[10] = "xxx";

	//printf("%s\n", strcpy(arr2, arr));

	//char arr[20] = "abc";
	//const char* p = "abcdef"; //行 //常量字符串不可以被修改
	////const char p[] = "abcdef"; //都行
	//
	//strcpy(arr, p);
	//printf("%s\n", arr);

    //return 0;
//}

//int main()
//{
//	char* arr = "abc"; //常量字符串
//	const char* arr = "abc"; //加上const可以直接报错，否则运行到崩溃
//
//	*arr = 'w'; //error Becaus常量字符串不可以被修改
//
//	return 0;
//}
//1
//2
//2024-3-25 Monday 13:32:32 March3月\
//模拟实现strcpy函数 - 版本1
//char* strcpy(char* destination, char* source)
//#include <stdio.h>
//
//void my_strcpy(char* dest, char* src)
//{
//	//将字符串src拷贝到dest，包括\0，dest空间原有的数据会被src覆盖
//	//问题：后面的空间还在啊？
//
//	while (*src != '\0')
//	{
//		*dest = *src; //一个字符一个字符的拷贝
//		//然后地址往后走
//		dest++;
//		src++;
//	}
//	//拷贝到\0，就来到这
//	//再把\0拷贝进去
//	*dest = *src;
//}
//
//int main()
//{
//	char arr1[] = "abc";
//	char arr2[20] = { 0 };
//
//	my_strcpy(arr2, arr1);
//	printf("%s\n", arr2);
//
//	//链式访问
//	//printf("%s\n", my_strcpy(arr2, arr1));
//
//	return 0;
//}
//1
//2
//2024-3-26 Tuesday 13:37:12 March3月
//版本2
//char* strcpy(char* destination, char* source)
//#include <stdio.h>
//
//void my_strcpy(char* dest, char* src)
//{
//	while (*dest++ = *src++) //直到赋值\0，判断结果为0，跳出循环，这样即做到了简化代码，又一次性达成了想要的效果
//	{
//		; //我发现这里不写分号也不会报错
//	}
//}
//
//int main()
//{
//	char arr1[] = "abc";
//	char arr2[20] = { 0 };
//
//	my_strcpy(arr2, arr1);
//
//	printf("%s\n", arr2);
//
//	return 0;
//}


//2024-3-27 Wednesday 13:30:56
//版本3
//char* strcpy(char* destination, const char* source)
//#include <stdio.h>
//#include <assert.h>
//
//void my_strcpy(char* dest, char* src)
//{
//	//NULL
//	assert(dest && src);
//
//	while (*dest++ = *src++)
//	{
//		;
//	}
//}
//
//int main()
//{
//	char arr1[] = "abc";
//	char arr2[20] = { 0 };
//
//	my_strcpy(arr2, arr1);
//
//	printf("%s\n", arr2);
//
//	return 0;
//}


//版本4
//dest指向的空间是需要改变的，但是srt指向的空间是不期望被改变的
//#include <stdio.h>
//#include <assert.h>
//
//void my_strcpy(char* dest, const char* src)
//{
//	assert(dest && src);
//	//逐个字符赋值
//	while (*dest++ = *src++)
//	{
//		;
//	}
//}
//
//int main()
//{
//	char arr1[] = "abc";
//	char arr2[20] = { 0 };
//
//	my_strcpy(arr2, arr1);
//
//	printf("%s\n", arr2);
//
//	return 0;
//}


//版本5
//#include <stdio.h>
//#include <assert.h>
//
//char* my_strcpy(char* dest, const char* src)
//{
//	char* ret = dest;
//
//	assert(dest && src);
//
//	while (*dest++ = *src++)
//	{
//		;
//	}
//
//	return ret; //返回目标空间的起始地址，保证目标地址不变
//}
//int main()
//{
//	char arr1[] = "abc";
//	char arr2[20] = { 0 };
//
//	printf("%s\n", my_strcpy(arr2, arr1));
//	printf("%s\n", arr2);
//
//	char* ret = my_strcpy(arr2, arr1);
//
//	char arr3[] = "abcd";
//	printf("%s\n", my_strcpy(ret, arr1));
//
//	return 0;
//}


//2024-3-29 Friday 13:48:41 March3月
//第16讲：字符函数和字符串函数
//⽬录：
//1. 字符分类函数
//2. 字符转换函数
//3. strlen的使⽤和模拟实现
//4. strcpy的使⽤和模拟实现
//5. strcat的使⽤和模拟实现
//6. strcmp的使⽤和模拟实现
//7. strncpy函数的使⽤
//8. strncat函数的使⽤
//9. strncmp函数的使⽤
//10. strstr的使⽤和模拟实现
//11. strtok函数的使⽤
//12. strerror函数的使⽤

//5. strcat的使⽤和模拟实现
//char* strncat(char* destination, const char* source)
//strcat - 字符串追加
//1. 目标空间中得有'\0'(从哪里开始追加)，源头字符串中得有'\0'，（追加到什么时候结束）
//2. 目标空间要足够大，目标要可以修改
//#include <stdio.h>
//#include <string.h>
//#include <assert.h>
//
//char* my_strncat(char* dest, const char* src)
//{
//	char* ret = dest;
//	assert(dest && src);
//	//1. 找到目标空间中的\0
//	//while (*dest != '\0')
//	//{
//	//	dest++;
//	//}
//	while (*dest++)
//	{
//		; //为什么用这个不行啊?
//	}
//
//	//2. 拷贝数据
//	while (*dest++ = *src++) //从\0开始加
//	{
//		;
//	}
//
//	return ret;
//}
//
//int main()
//{
//	char arr1[20] = "hello "; //hello world
//	char* p = "world"; //常量字符串不可以修改，符合const
//
//	//printf("%s\n", strcat(arr1, p)); //为什么可以利用返回值打印？
//	//printf("%s\n", my_strcat(arr1, p));
//	//printf("%s\n", arr1);
//
//	return 0;
//}
//1
//2
//char* strcat(char* destination, const source)
//字符串追加
#include <stdio.h>
#include <assert.h>

char* my_strncat(char* dest, char* src)
{
	char* ret = dest;
	assert(dest && src);
	
		//1. 找到目标空间中的\0
		while (*dest != '\0')
		{
			dest++;
		}
	
	//2. 拷贝数据

	while (*dest++ = *src++)
	{
		;
	}

	return ret;
}

int main()
{
	char arr1[] = "hello ";
	my_strncat(arr1, arr1);

	printf("%s\n", arr1);

	return 0;
}

//前面把strncat写成strcat了，注意一下！！！












